package com.liuyu.publisher.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;

@Slf4j
@Configuration
//ApplicationContextAware: 在Spring容器（Bean工厂）创建好的时候，通知咱们
public class CommonConfig implements ApplicationContextAware {
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        RabbitTemplate rabbitTemplate = applicationContext.getBean(RabbitTemplate.class);

        //设置消息到队列回调
        rabbitTemplate.setReturnsCallback(returnedMessage -> {

            //因为延迟消息在达到交换机时不会立马投递到队列而是暂存在内存中只有当延迟消息的时间到了之后才会被投递到队列中，所有这个returncallback会返回nack所以需要判断
            Long receivedDelay = returnedMessage.getMessage().getMessageProperties().getReceivedDelayLong();
            if (receivedDelay != null && receivedDelay > 0) {
                //判断是延迟消息则跳过returncallback处理
                return;
            }
            //处理路由失败的消息
            log.error("消息路由到队列失败:message={},replyCode={},replyText={},exchange={},routingKey={}"
                    , returnedMessage.getMessage(), returnedMessage.getReplyCode(), returnedMessage.getReplyText(), returnedMessage.getExchange(), returnedMessage.getRoutingKey());
            //可以重发或者记录日志或者加入定时任务
        });

        //设置消息到交换机失败回调
        rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
            String body = "";
            //判断是否是EnhancedCorrelationData
            if (correlationData instanceof EnhancedCorrelationData) {
                body = ((EnhancedCorrelationData) correlationData).getBody();
            }
            if (ack) {
                log.info("消息到交换机正常,消息id:{}", body);
            } else {
                log.error("消息到达交换机失败,message_id={},message_info={},cause={}", correlationData.getId(), body, cause);
            }
        });
    }
}
